home *** CD-ROM | disk | FTP | other *** search
Text File | 1991-07-25 | 30.9 KB | 1,071 lines | [TEXT/PJMM] |
- program LogOMat;
-
- { Program to backup, sort and zero user minutes in a Red Ryder Host UserLog }
- { and to reset CallerLog and TabbyLog. }
-
- { Written by Pete Johnson for the Glassell Park BBS 213-254-4133 }
-
- { Version 1.8 }
-
- { Date of last revision: Jan. 27, 1991 }
-
- { Known bugs: Alter veteran users doesn't set or clear flags right. }
- { BU Tabby log by days not implemented. }
- { Monthly Tabby.Arch not implemented. }
- { Need to rework so that BackupPath is used for all archives. }
-
- uses
- Globals, HelloTabby, ConfigureLOM;
-
- const
- ARRAYLIMIT = 3000;
- DAYSECS = 86400; { hours * mins * secs in a day }
- DELETED = 64;
- MySignature = longint('LMat');
-
- runDlog = 1001; { Resource type: DLOG }
-
- nextLaunchStr = 500; { Resource type: STR }
- defaultsStr = 501;
- BackupPathStr = 504;
- veteranStr = 505;
- flagStr = 506;
- textTypeStr = 507;
- levelToDeleteStr = 508;
- promotionStr = 509;
- tabbyLogArchLimitStr = 510;
- oneCallLimitStr = 511;
- deleteOldUsersStr = 512;
- checkLevelStr = 513;
- None = 0;{ no compression}
- Faster = 1;{ faster compression}
- Fast = 2;{ fast compression}
- Better = 3;{ better compression}
- Optimal = 4;{ optimal compression - 1.1 or later}
- BestGuess = 5;{ best guess- faster, but not always as good - 1.1 or later}
-
- type
- WhenCalled = packed array[1..6] of char;
- UserRecord = packed record
- FirstName: string[15];
- LastName: string[15];
- CallingFromAndPW: packed array[1..40] of char;
- NumberOfCalls: integer;
- DateLastCalled: WhenCalled;
- TCMRRF: packed array[1..6] of char; {Time, Clearance, Minutes last call, Reserved, Reserved, Flags}
- Uploads: integer;
- Downloads: integer;
- PrivMsg: integer;
- PubMsg: integer;
- MRRF: packed array[1..6] of char;
- HiMsgRead: longint;
- CombinedReads: packed array[1..32] of char
- end;
- FileSpecPtr = ^FileSpec;
- FileSpec = record
- v: Integer;{ volume refNum}
- d: Longint;{ directory id}
- n: string[31];{ file/folder name}
- method: signedbyte;{ comp method - used in compression only}
- deleteIt: boolean;{ delete original file/folder when done?}
- end;
- FileListHdl = ^FileListPtr;
- FileListPtr = ^FileListRec;
- FileListRec = record
- count: integer;{ # of files/folders below}
- ary: array[0..0] of filespec;{ array of files to act on}
- end;
-
- var
- ThisUser: UserRecord;
- DialogPointer: DialogPtr;
- fndrInfo: FInfo;
- NewRefNum, ULRefNum, Count, StuffRef: integer;
- logicalEOF, ULRecSize: longint;
- Today: DateTimeRec;
- ResourceHandle: StringHandle;
- StuffResource: Handle;
- savePort: GrafPtr;
- dispRect: rect;
-
- {----------------------------------------------------------------- }
-
- function GetDirInfo (ourPath: str255; var ourVRef: integer): OSErr;
-
- var
- i: integer;
- ourDirRef: longint;
- myWDPBRec: WDPBRec;
- Error: OSErr;
- tempString: str255;
-
- begin
- while (ourPath[length(ourPath)] <> ':') & (length(ourPath) > 1) do
- ourPath := copy(ourPath, 1, length(ourPath) - 1);
- tempString := ourPath; {make an extra copy since HGetVol truncates the string}
- Error := HGetVol(@tempString, ourVRef, ourDirRef);
- with myWDPBRec do
- begin
- ioNamePtr := @ourPath;
- ioVRefNum := ourVRef;
- ioWDDirID := ourDirRef;
- ioWDProcID := MySignature;
- Error := PBOpenWD(@myWDPBRec, false);
- if ioVRefNum <> vRefNum then {StuffIt doesn't like being fed a working }
- ourVRef := ioVRefNum {directory when file is in default directory }
- end;
- GetDirInfo := Error
- end;
-
- {----------------------------------------------------------------- }
-
- procedure CloseWD (tempVRef: longint);
-
- var
- myWDPBRec: WDPBRec;
-
- begin
- with myWDPBRec do
- begin
- ioNamePtr := nil;
- ioVRefNum := tempVRef;
- ioWDIndex := 0;
- Err := PBCloseWD(@myWDPBRec, false)
- end
- end;
-
- {----------------------------------------------------------------- }
-
- function GetPath (Input: str255): str255;
-
- begin
- while not (Input[length(Input)] in [':']) & (length(Input) > 1) do
- Input := copy(Input, 1, length(Input) - 1);
- if length(Input) = 1 then
- Input := ':';
- GetPath := Input
- end;
-
- { ------------------------------------------------------ }
-
- function Stuff (theFiles: FileListHdl; { list of files to compress}
- destFile: FileSpecPtr; { result file name/location}
- title: Str255; { title of progress windows}
- Addr: Ptr): OSErr; { address to jump to (start of the resource)}
- inline
- $205F, $4E90; { pop last param & jump to it}
-
- {----------------------------------------------------------------- }
-
- function FindStuffIt: boolean;
-
- var
- error: OSErr;
- theWorld: SysEnvRec;
- CheckRef, origVRef, StuffVRef: integer;
-
- begin
- error := GetVol(nil, origVRef);
- error := SysEnvirons(1, theWorld);
- StuffVRef := theWorld.sysVRefNum; {it's in the System Folder}
- error := SetVol(nil, StuffVRef);
- if error = noErr then
- StuffRef := OpenResFile(':Extensions:StuffIt Engine™');
- if (StuffRef <> -1) then
- begin
- StuffResource := NewHandle(sizeOf(Handle));
- StuffResource := Get1IndResource('MENC', 1);
- GetPort(savePort); { Only needed when calling v1.0 of the engine}
- end;
- error := SetVol(nil, origVRef);
- if (error = noErr) & (StuffRef <> -1) then
- FindStuffIt := true
- else
- FindStuffIt := false
- end;
-
- {----------------------------------------------------------------- }
-
- procedure CloseStuffIt;
-
- begin
- ReleaseResource(StuffResource);
- CloseResFile(StuffRef);
- if StuffResource <> nil then
- DisposHandle(StuffResource);
- end;
-
- {----------------------------------------------------------------- }
-
- function Int2Char (Number: integer): char;
-
- { Function changes integer to character. }
-
- begin
- Int2Char := chr(Number + ord('0'))
- end;
-
- { ------------------------------------------------------ }
-
- function BigString (Number: integer): string;
-
- { Function changes two-digit number to a two-character string. }
-
- begin
- BigString := concat(Int2Char(Number div 10), Int2Char(Number mod 10))
- end;
-
- { ------------------------------------------------------ }
-
- procedure Wr (fref: integer; length: longint; thepointer: Ptr);
-
- begin
- Err := FSWrite(fref, length, thepointer)
- end;
-
- { ------------------------------------------------------ }
-
- function WrLn (fref: integer; theStr: str255): OSErr;
- var
- CR: signedByte;
-
- begin
- CR := 13;
- Wr(fref, length(theStr), pointer(ord(@theStr) + 1));
- Wr(fref, 1, @CR)
- end;
-
- { ------------------------------------------------------ }
-
- procedure MakeDateline;
-
- begin
- GetTime(Today);
- Date2Secs(Today, NowSecs);
- { The BigString function in the following section turns a two-digit integer }
- { into a two-character string. If there are fewer than two digits, the string }
- { contains a leading '0'. }
-
- DateString := concat(BigString(Today.Month), '/');
- DateString := concat(DateString, BigString(Today.Day), '/');
- DateString := concat(DateString, BigString(Today.Year - 1900))
-
- end;
-
- { ------------------------------------------------------ }
-
- procedure GetSTR;
-
- var
- TheString: str255;
- CommaPlace: integer;
-
- begin
- TheString := GetString(defaultsStr)^^;
-
- while length(TheString) < 14 do
- TheString := concat(TheString, 'Y');
-
- if TheString[1] = 'Y' then
- DeleteByLevel := true
- else
- DeleteByLevel := false;
-
- if TheString[2] = 'Y' then
- SkipDeletes := true
- else
- SkipDeletes := false;
-
- if TheString[3] = 'Y' then
- Backup := true
- else
- Backup := false;
-
- if TheString[4] = 'Y' then
- ZeroMin := true
- else
- ZeroMin := false;
-
- if TheString[5] = 'Y' then
- SortUL := true
- else
- SortUL := false;
-
- if TheString[6] = 'Y' then
- ResetCL := true
- else
- ResetCL := false;
-
- if TheString[7] = 'Y' then
- ResetTL := true
- else
- ResetTL := false;
-
- if TheString[8] = 'Y' then
- MonthlyCLArc := true
- else
- MonthlyCLArc := false;
-
- if TheString[9] = 'Y' then
- LogDeletes := true
- else
- LogDeletes := false;
-
- if TheString[10] = 'Y' then
- KillOldOneCalls := true
- else
- KillOldOneCalls := false;
-
- if TheString[11] = 'Y' then
- AlterVeterans := true
- else
- AlterVeterans := false;
-
- if TheString[12] = 'Y' then
- MonthlyTLArc := true
- else
- MonthlyTLArc := false;
-
- if TheString[13] = 'S' then
- SetTheFlag := true
- else
- SetTheFlag := false;
-
- if TheString[14] = 'K' then
- TLKLimit := true
- else
- TLKLimit := false;
-
- if TheString[15] = 'S' then
- UseStuffit := true
- else
- UseStuffit := false;
-
- DeleteLevelString := GetString(levelToDeleteStr)^^;
- StringToNum(DeleteLevelString, DeleteLevel);
- DeleteLevel := Byte(BitAnd(DeleteLevel, 255));
-
- PromotionString := GetString(promotionStr)^^; { format of string is Y9,10,25 }
- Newcomer := 0; { first letter is 'Y' or 'N' }
- Approved := 0; { first integer is Newcomer }
- NewTime := 0; { second integer is Approved }
- if PromotionString[1] = 'Y' then { third integer is NewTime }
- begin
- ChangeLevel := true;
- CommaPlace := pos(',', PromotionString);
- if CommaPlace > 0 then
- begin
- TheString := copy(PromotionString, 2, CommaPlace - 2); {start at 2 to skip 'Y' or 'N', CommaPlace - 2 is length }
- StringToNum(TheString, Newcomer);
- TheString := copy(PromotionString, CommaPlace + 1, 255);
- CommaPlace := pos(',', TheString);
- if CommaPlace > 0 then
- begin
- TempString := copy(TheString, 1, CommaPlace - 1);
- StringToNum(TempString, Approved);
- TempString := copy(TheString, CommaPlace + 1, 255);
- StringToNum(TempString, NewTime)
- end
- end
- else
- ChangeLevel := false
- end;
-
- TabbyLimitString := GetString(tabbyLogArchLimitStr)^^; { format of string is YK100 (number in K) or }
- if TabbyLimitString[1] = 'Y' then { YD100 with K or D for KBytes or Days. }
- begin
- TabbyLimit := true;
- if TabbyLimitString[2] = 'D' then
- TLKLimit := false
- else
- TLKLimit := true;
- StringToNum(copy(TabbyLimitString, 3, 255), TabbyLimitSize)
- end
- else
- begin
- TabbyLimit := false;
- TabbyLimitSize := 0
- end;
-
- OneCallLimitString := GetString(oneCallLimitStr)^^;
- StringToNum(OneCallLimitString, OneCallLimit);
-
- TheString := GetString(deleteOldUsersStr)^^; { format of string is Y100 (number in K) }
- if TheString[1] = 'Y' then
- begin
- DeleteOldUsers := true;
- StringToNum(copy(GetString(deleteOldUsersStr)^^, 2, 255), Inactivity)
- end
- else
- begin
- DeleteOldUsers := false;
- Inactivity := 0
- end;
-
- CheckLevStr := GetString(checkLevelStr)^^; { format of string is '0' to '255') }
- StringToNum(CheckLevStr, CheckLevLong);
-
- TEXTType := GetString(textTypeStr)^^;
-
- BackupPath := GetString(BackupPathStr)^^;
-
- VetCallsText := GetString(veteranStr)^^;
- StringToNum(VetCallsText, VetCalls);
-
- FlagNumText := GetString(flagStr)^^;
- StringToNum(FlagNumText, FlagNum);
-
- end;
-
- { ------------------------------------------------------ }
-
- function ReadConfig: boolean;
-
- { Reads Config file and returns Path:CallerLog, Path:UserLog, Path:MESSAGES, SysopName (all caps) and }
- { NextLaunchDateRec. }
-
- var
- AString: str255;
- VolumeRef, ConfigRefNum: integer;
- FileEnd, CharsToSend, NextLaunchTime: longint;
- ConfigErr: OSErr;
- VolName: STR255;
-
- begin
-
- ConfigErr := GetVol(@VolName, VolumeRef); { Get volume ref # for default volume }
- ULPath := '';
- if (ConfigErr = NoErr) then
- ConfigErr := FSOpen(':Config', VolumeRef, ConfigRefNum);
- if (ConfigErr = NoErr) then
- ConfigErr := GetEOF(ConfigRefNum, FileEnd);
-
- if (FileEnd > 317) & (ConfigErr = NoErr) then { Make sure file is longer than our deepest SetFPos (it should be 349) }
- begin
- CharsToSend := 41;
- ConfigErr := SetFPos(ConfigRefNum, fsFromStart, 57);
- ConfigErr := FSRead(ConfigRefNum, CharsToSend, @AString);
- if length(AString) > 0 then
- ULPath := AString
- else
- ULPath := '';
- ULPath := concat(ULPath, ':UserLog');
-
- CharsToSend := 41;
- ConfigErr := SetFPos(ConfigRefNum, fsFromStart, 98);
- ConfigErr := FSRead(ConfigRefNum, CharsToSend, @AString);
- if length(AString) > 0 then
- CLPath := AString
- else
- CLPath := '';
- CLPath := concat(CLPath, ':CallerLog');
- end; { if FileEnd > 317 }
-
- if (ConfigErr = NoErr) then
- ReadConfig := true
- else
- ReadConfig := false;
- ConfigErr := FSClose(ConfigRefNum);
- end;
-
- { ------------------------------------------------------ }
-
- procedure SortUserLog;
-
- type
- UserPointer = ^UserRecord;
- UserHandle = ^UserPointer;
- UserArray = array[1..ARRAYLIMIT] of UserHandle;
- SortRecord = record
- IndexNo: integer;
- IndexString: packed array[1..7] of char;
- end;
- SortPointer = ^SortRecord;
- SortHandle = ^SortPointer;
- SortArray = array[1..ARRAYLIMIT] of SortHandle;
-
- var
- TheUserLog: UserArray;
- ThisArray: SortArray;
- UserCount1, UserCount2, SortedUser, ULRef: integer;
- HeadCount: longint;
-
- procedure QuickSort (Start, Finish: integer; var TheArray: SortArray);
-
- { Sorts array Users by Clearance+Date field using QuickSort }
-
- var
- Left, Right: integer;
- StarterValue: packed array[1..7] of char;
- Temp: SortHandle;
-
- begin
- Left := Start;
- Right := Finish;
- StarterValue := TheArray[(Start + Finish) div 2]^^.IndexString; { Pick a starter }
- repeat
- while TheArray[Left]^^.IndexString < StarterValue do
- Left := Left + 1; { Find a bigger value on the left }
- while StarterValue < TheArray[Right]^^.IndexString do
- Right := Right - 1; { Find a smaller value on the right }
- if Left <= Right then
- begin {If we haven't gone too far... }
- Temp := TheArray[Left];
- TheArray[Left] := TheArray[Right];
- TheArray[Right] := Temp;
- Left := Left + 1;
- Right := Right - 1
- end; { then }
- until Right <= Left;
- if Start < Right then
- QuickSort(Start, Right, TheArray);
- if Left < Finish then
- QuickSort(Left, Finish, TheArray)
- end; { procedure QuickSort }
-
- begin
- Err := FSOpen(ULPath, vRefNum, ULRef);
- Err := SetFPos(ULRef, fsFromStart, ULRecSize); { Sysop is at seek position zero, so we skip it }
- Err := GetEOF(ULRef, logicalEOF);
- HeadCount := logicalEOF div ULRecSize;
- UserCount1 := 1;
- if (HeadCount <= ARRAYLIMIT) & (HeadCount > 2) then
- begin
- for UserCount1 := 2 to HeadCount do { skip 1 to allow for missing sysop }
- begin
- TheUserLog[UserCount1] := UserHandle(NewHandle(ULRecSize));
- Err := FSRead(ULRef, ULRecSize, Ptr(TheUserLog[UserCount1]^));
- ThisArray[UserCount1] := SortHandle(NewHandle(SizeOf(SortRecord)));
- ThisArray[UserCount1]^^.IndexNo := UserCount1;
- ThisArray[UserCount1]^^.IndexString := concat(TheUserLog[UserCount1]^^.TCMRRF[2], TheUserLog[UserCount1]^^.DateLastCalled);
- end; { for UserCount1 := 1 to HeadCount - 1 }
-
- QuickSort(2, HeadCount, ThisArray);
-
- Err := SetFPos(ULRef, fsFromStart, ULRecSize); { Sysop is at seek position zero, so we skip it }
-
- for UserCount2 := HeadCount downto 2 do { Write in reverse to get proper order }
- begin
- SortedUser := ThisArray[UserCount2]^^.IndexNo;
- Err := FSWrite(ULRef, ULRecSize, Ptr(TheUserLog[SortedUser]^));
- DisposHandle(Handle(TheUserLog[SortedUser]));
- DisposHandle(Handle(ThisArray[UserCount2]));
- end; { for UserCount2 := UserCount1 downto 1 }
-
- Err := FSClose(ULRef)
- end { (HeadCount <= ARRAYLIMIT) & (HeadCount > 2) }
- end;
-
- { ------------------------------------------------------ }
-
- procedure ZeroMinutes;
-
- var
- ZeroMinCount, ByteSize: longint;
- TimeByte: byte;
-
- begin
- TimeByte := 0;
- ByteSize := 1;
- Err := FSOpen(ULPath, vRefNum, ULRefNum);
- Err := GetEOF(ULRefNum, logicalEOF);
- for ZeroMinCount := 1 to (logicalEOF div sizeOf(UserRecord)) do
- begin
- Err := SetFPos(ULRefNum, fsFromStart, ((ZeroMinCount - 1) * sizeOf(UserRecord)) + 82);
- Err := FSWrite(ULRefNum, ByteSize, @TimeByte);
- end;
- Err := FSClose(ULRefNum);
- end;
-
- { ------------------------------------------------------ }
-
- function UserHasExpired (DateOfLastCall: WhenCalled; DaysAllowed: longint): boolean;
-
- var
- UserDTR: DateTimeRec;
- UserSecs: longint;
-
- begin
- UserDTR.Year := BitAnd(ord(DateOfLastCall[1]), 255) + 1900;
- UserDTR.Month := BitAnd(ord(DateOfLastCall[2]), 255);
- UserDTR.Day := BitAnd(ord(DateOfLastCall[3]), 255);
- UserDTR.Hour := 0;
- UserDTR.Minute := 0;
- UserDTR.Second := 0;
- Date2Secs(UserDTR, UserSecs);
- if (NowSecs - UserSecs) > (DAYSECS * DaysAllowed) then
- UserHasExpired := true
- else
- UserHasExpired := false
- end;
-
- { ------------------------------------------------------ }
- procedure GetFromAndPW (var From, PW: str255);
-
- var
- Counter: integer;
-
- begin
- From := '';
- for Counter := 2 to ord(ThisUser.CallingFromAndPW[1]) + 1 do
- From := concat(From, ThisUser.CallingFromAndPW[Counter]);
- PW := '';
- for Counter := 33 to ord(ThisUser.CallingFromAndPW[32]) + 32 do
- PW := concat(PW, ThisUser.CallingFromAndPW[Counter]);
- end;
-
- { ------------------------------------------------------ }
-
- procedure WriteDeleteLog (ReasonDeleted: str255);
-
- var
- DeleteRef, Counter: integer;
- ULDeleteFile, Password, FromString, LogString: str255;
-
- begin
- ULDeleteFile := concat(BackupPath, 'Users Deleted');
- Err := FSOpen(ULDeleteFile, vRefNum, DeleteRef);
- if Err <> NoErr then
- begin
- Err := Create(ULDeleteFile, vRefNum, TEXTType, 'TEXT');
- Err := FSOpen(ULDeleteFile, vRefNum, DeleteRef);
- Err := WrLn(DeleteRef, ' Calls Last UL DL Pub Pri Lev Min Reason');
- end;
- if Err = NoErr then
- begin
- Err := SetFPos(DeleteRef, FSFromLEOF, 0);
- GetFromAndPW(FromString, Password);
- with ThisUser do
- begin
- LogString := concat(FirstName, ' ', LastName, ' from ', FromString);
- LogString := concat(LogString, ' [', Password, ']', ENDLINE);
- LogString := concat(LogString, DateString, ' ', StringOf(NumberOfCalls : 4), ' ');
- LogString := concat(LogString, BigString(ord(DateLastCalled[2])), '/');
- LogString := concat(LogString, BigString(ord(DateLastCalled[3])), '/');
- LogString := concat(LogString, BigString(ord(DateLastCalled[1])), ' ');
- LogString := concat(LogString, StringOf(Uploads : 4), ' ');
- LogString := concat(LogString, StringOf(Downloads : 4), ' ');
- LogString := concat(LogString, StringOf(PubMsg : 4), ' ');
- LogString := concat(LogString, StringOf(PrivMsg : 4), ' ');
- LogString := concat(LogString, StringOf(ord(TCMRRF[2]) : 3), ' ');
- LogString := concat(LogString, StringOf(ord(TCMRRF[1]) : 3), ' ', ReasonDeleted)
- end; {with ThisUser}
- Err := WrLn(DeleteRef, LogString)
- end;
- Err := FSClose(DeleteRef)
- end;
-
- { ------------------------------------------------------ }
-
- procedure BackUserLog;
-
- const
- MaxBadNames = 100;
- MaxFileChars = 10000;
-
- var
- FilePointer: Ptr;
- tempWD: integer;
-
- var
- ULCounter: longint;
- BadNameFile, HowManyBadNames, Counter, i, ULCopyRefNum: integer;
- BadNames: array[1..MaxBadNames] of string[15];
- GoodUser: boolean;
- ReasonDeleted, SitName: str255;
- StuffFilesHandle: FileListHdl;
- destFile: FileSpec;
- HowManyCharacters, tempDirRef, tempVRef: longint;
-
- begin
- for Counter := 1 to MaxBadNames do
- BadNames[Counter] := '';
- Err := FSOpen('Bad User Names', vRefNum, BadNameFile);
- Counter := 1;
- while (Err = NoErr) & (Counter < MaxBadNames + 1) do
- begin
- Err := ReadALine(BadNameFile, BadNames[Counter]);
- if BadNames[Counter] = '' then
- leave;
- Counter := succ(Counter);
- end;
- HowManyBadNames := Counter - 1;
- Err := FSClose(BadNameFile);
- NewULog := concat(ULPath, '.$$$');
- TheBAK := concat(ULPath, '.BAK');
- Err := GetFInfo(NewULog, vRefNum, fndrInfo);
- if Err = noErr then
- begin
- with fndrInfo do
- begin
- fndrInfo.fdType := 'ULOG';
- fndrInfo.fdCreator := 'ULED'
- end;
- Err := SetFInfo(NewULog, vRefNum, fndrInfo);
- end
- else
- Err := Create(NewULog, vRefNum, 'ULED', 'ULOG');
- Err := FSOpen(NewULog, vRefNum, NewRefNum);
- Err := SetFPos(NewRefNum, fsFromStart, 0);
- Err := FSOpen(ULPath, vRefNum, ULRefNum);
- Err := GetEOF(ULRefNum, logicalEOF);
- Err := SetFPos(ULRefNum, fsFromStart, 0);
- for ULCounter := 1 to (logicalEOF div ULRecSize) do
- begin
- Err := FSRead(ULRefNum, ULRecSize, @ThisUser);
- ReasonDeleted := 'Unknown';
- if ChangeLevel then
- if (ThisUser.TCMRRF[2] = chr(Newcomer)) then
- begin
- GoodUser := true;
- for Counter := 1 to HowManyBadNames do
- if (EqualString(ThisUser.FirstName, BadNames[Counter], false, false)) | (EqualString(ThisUser.LastName, BadNames[Counter], false, false)) then
- GoodUser := false;
- if GoodUser then
- begin
- ThisUser.TCMRRF[1] := chr(NewTime);
- ThisUser.TCMRRF[2] := chr(Approved)
- end
- else
- begin
- ThisUser.TCMRRF[1] := chr(0); { zero time }
- ThisUser.TCMRRF[2] := chr(0); { zero access }
- ThisUser.TCMRRF[6] := chr(DELETED); { delete }
- ReasonDeleted := 'Bad Name'
- end
- end; { if (ThisUser.TCMRRF[2] = chr(Newcomer)) }
- if (ord(ThisUser.TCMRRF[2]) <= CheckLevLong) & (ULCounter <> 1) then
- begin
- if DeleteOldUsers then
- if UserHasExpired(ThisUser.DateLastCalled, Inactivity) then
- begin
- ThisUser.TCMRRF[6] := chr(DELETED);
- ReasonDeleted := 'Inactive'
- end;
- if KillOldOneCalls then
- if (ThisUser.NumberOfCalls < 2) then
- if UserHasExpired(ThisUser.DateLastCalled, OneCallLimit) then
- if ((ThisUser.Uploads + ThisUser.Downloads + ThisUser.PrivMsg + ThisUser.PubMsg) < 1) then
- begin
- ThisUser.TCMRRF[6] := chr(DELETED);
- ReasonDeleted := 'One-Timer'
- end;
- end; { if (ord(ThisUser.TCMRRF[2]) <= CheckLevLong) & (ULCounter <> 1) }
- if AlterVeterans & (ThisUser.NumberOfCalls > VetCalls) then
- if SetTheFlag then
- ThisUser.MRRF[6 - ((FlagNum - 1) div 8)] := chr(BitOr(ord(ThisUser.MRRF[6 - ((FlagNum - 1) div 8)]), FlagNum mod 8))
- else
- ThisUser.MRRF[6 - ((FlagNum - 1) div 8)] := chr(BitXor(ord(ThisUser.MRRF[6 - ((FlagNum - 1) div 8)]), FlagNum mod 8));
- if (ThisUser.TCMRRF[2] = chr(DeleteLevel)) & DeleteByLevel then
- ReasonDeleted := 'Bad Level';
- { Next section checks TCMRFF byte 2 to see if clearance is valid and bit 7 of TCMRFF byte 6 to see if user is deleted }
- if (ThisUser.TCMRRF[2] <> chr(DeleteLevel)) | (not DeleteByLevel) then
- if (BitAnd(ord(ThisUser.TCMRRF[6]), DELETED) <> DELETED) | (not SkipDeletes) then
- Err := FSWrite(NewRefNum, ULRecSize, @ThisUser);
- if (BitAnd(ord(ThisUser.TCMRRF[6]), DELETED) = DELETED) & SkipDeletes & LogDeletes then
- WriteDeleteLog(ReasonDeleted);
- end;
- Err := FSClose(ULRefNum);
- Err := FSClose(NewRefNum);
- Err := FSDelete(TheBAK, vRefNum); { Delete old Userlog.BAK }
- Err := Rename(ULPath, vRefNum, TheBAK); { Rename Userlog to Userlog.BAK }
- Err := Rename(NewULog, vRefNum, ULPath); { Rename Userlog.$$$ to Userlog }
-
- Err := FSOpen(TheBAK, vRefNum, ULRefNum);
- Err := FSDelete(concat(BackupPath, 'UL.bak'), vRefNum);
- Err := FSDelete(concat(BackupPath, 'UL.sit'), vRefNum);
- Err := Create(concat(BackupPath, 'UL.bak'), vRefNum, 'ULED', 'ULOG');
- if Err = noErr then
- Err := FSOpen(concat(BackupPath, 'UL.bak'), vRefNum, ULCopyRefNum);
- HowManyCharacters := MaxFileChars;
- FilePointer := NewPtr(HowManyCharacters);
- while (Err = noErr) & (HowManyCharacters = MaxFileChars) do
- begin
- Err := FSRead(ULRefNum, HowManyCharacters, FilePointer);
- Err := FSWrite(ULCopyRefNum, HowManyCharacters, FilePointer)
- end;
- Err := FSClose(ULRefNum);
- Err := FSClose(ULCopyRefNum);
- Err := FSDelete(TheBAK, vRefNum); { Delete old Userlog.BAK }
-
- if StuffItAvail & UseStuffit then
- begin
- EraseRect(dispRect);
- MoveTo(dispRect.left + 2, dispRect.bottom - 2);
- DrawString('Stuffing Userlog.bak…');
- Err := GetDirInfo(BackupPath, tempWD); {••• fix later}
-
- if Err = NoErr then
- begin
- with destFile do
- begin
- v := tempVRef;
- d := tempDirRef;
- n := 'UL.sit';
- method := Better;
- deleteIt := false;
- end;
- StuffFilesHandle := FileListHdl(NewHandle((sizeOf(FileListHdl)) + (1 * sizeOf(filespec))));
- with StuffFilesHandle^^ do
- begin
- count := 1;
- with ary[0] do
- begin
- v := tempVRef;
- d := tempDirRef;
- n := 'UL.bak';
- method := Better;
- deleteIt := true
- end
- end;
- HLock(StuffResource);
- Err := Stuff(StuffFilesHandle, @destFile, 'Shrinking UserLog', StuffResource^);
- HUnlock(StuffResource);
- DisposHandle(Handle(StuffFilesHandle));
- CloseWD(tempVRef);
- SetPort(savePort) { Only needed when calling v1.0 of the engine}
- end
- end
- end;
-
- { ------------------------------------------------------ }
-
- procedure ResetLog (LogPath: STR255);
-
- var
- TheLogArchive, LogString, TheTempFile: STR255;
- LogRef, LogArcRef, TempRef: integer;
- fndrInfo: FInfo;
- Quit: boolean;
- LogPos: longint;
-
- begin
- Err := FSOpen(LogPath, vRefNum, LogRef);
- Err := GetEOF(LogRef, logicalEOF);
- TheLogArchive := concat(LogPath, '.Arch');
- Err := GetFInfo(TheLogArchive, vRefNum, fndrInfo);
- if Err = noErr then
- begin
- with fndrInfo do
- begin
- fndrInfo.fdType := 'TEXT';
- fndrInfo.fdCreator := TEXTType
- end;
- Err := SetFInfo(TheLogArchive, vRefNum, fndrInfo);
- end
- else
- Err := Create(TheLogArchive, vRefNum, TEXTType, 'TEXT');
- Err := FSOpen(TheLogArchive, vRefNum, LogArcRef);
- Err := SetFPos(LogArcRef, fsFromLEOF, 0);
-
- Quit := false;
- Err := GetFPos(LogRef, LogPos);
-
- while (LogPos < logicalEOF) and (not Quit) do
- begin
- Err := ReadALine(LogRef, LogString);
- if pos(DateString, LogString) <> 1 then
- Err := WrLn(LogArcRef, LogString)
- else
- Quit := true;
- Err := GetFPos(LogRef, LogPos);
- end;
-
- Err := FSClose(LogArcRef);
- TheTempFile := concat(LogPath, '.$$$');
- Err := FSDelete(TheTempFile, vRefNum);
- Err := Create(TheTempFile, vRefNum, TEXTType, 'TEXT');
- Err := FSOpen(TheTempFile, vRefNum, TempRef);
-
- if pos(DateString, LogString) = 1 then
- Err := WrLn(TempRef, LogString);
-
- while (LogPos < logicalEOF) do
- begin
- Err := ReadALine(LogRef, LogString);
- Err := WrLn(TempRef, LogString);
- Err := GetFPos(LogRef, LogPos);
- end;
-
- Err := FSClose(TempRef);
- Err := FSClose(LogRef);
- Err := FSDelete(LogPath, vRefNum);
- Err := Rename(TheTempFile, vRefNum, LogPath);
-
- end;
-
- { ------------------------------------------------------ }
-
- procedure DoMonthlyArc;
-
- var
- MonthlyName: str255;
- ThisMonth, ThisYear: integer;
-
- begin
- if Today.Day = 1 then
- begin
- if Today.Month = 1 then
- begin
- ThisMonth := 12;
- ThisYear := pred(Today.Year)
- end
- else
- begin
- ThisMonth := pred(Today.Month);
- ThisYear := Today.Year;
- end;
- MonthlyName := concat(BackupPath, 'CallerLog ', BigString(ThisMonth), '/', stringOf((ThisYear mod 100) : 1));
- Err := Rename(concat(BackupPath, 'CallerLog.Arch'), vRefNum, MonthlyName);
- Err := Create(concat(BackupPath, 'CallerLog.Arch'), vRefNum, TEXTType, 'TEXT')
- end
- end;
-
- { ------------------------------------------------------ }
-
- procedure TrimLog (LogPath: STR255);
-
- const
- MaxBufSize = 10000;
-
- type
- Buffer = packed array[1..MaxBufSize] of char;
- BufPtr = ^Buffer;
- BufHdl = ^BufPtr;
-
- var
- TempLogArchive, LogString: STR255;
- LogRef, TempLogRef: integer;
- fndrInfo: FInfo;
- TransferChars: longint;
- MyBufHdl: BufHdl;
-
- begin
- Err := FSOpen(LogPath, vRefNum, LogRef);
- Err := GetEOF(LogRef, logicalEOF);
-
- if (logicalEOF > (TabbyLimitSize * 1024)) then
- begin
- TempLogArchive := concat(LogPath, '$$$');
- Err := GetFInfo(TempLogArchive, vRefNum, fndrInfo);
- if Err = noErr then
- begin
- fndrInfo.fdType := 'TEXT';
- fndrInfo.fdCreator := TEXTType;
- Err := SetFInfo(TempLogArchive, vRefNum, fndrInfo);
- end
- else
- Err := Create(TempLogArchive, vRefNum, TEXTType, 'TEXT');
- Err := FSOpen(TempLogArchive, vRefNum, TempLogRef);
- TransferChars := MaxBufSize;
- MyBufHdl := BufHdl(NewHandle(MaxBufSize));
- HLock(Handle(MyBufHdl));
- Err := SetFPos(LogRef, fsFromLEOF, -(TabbyLimitSize * 1024));
- Err := ReadALine(LogRef, LogString); {discard any partial lines}
- while (Err = NoErr) do
- begin
- Err := FSRead(LogRef, TransferChars, Ptr(MyBufHdl^));
- if (TransferChars > 0) then
- Err := FSWrite(TempLogRef, TransferChars, Ptr(MyBufHdl^))
- end;
- HUnlock(Handle(MyBufHdl));
- DisposHandle(Handle(MyBufHdl));
- Err := FSClose(TempLogRef);
- Err := FSClose(LogRef);
- Err := FSDelete(LogPath, vRefNum);
- Err := Rename(TempLogArchive, vRefNum, LogPath)
- end
- else
- Err := FSClose(LogRef)
- end;
-
- { ------------------------------------------------------ }
-
- var
- itemType: integer;
- itemHandle: Handle;
-
- begin
- CurrentResFile := CurResFile;
- GetSTR;
- MakeDateline;
- if Button then
- ConfigureDialog { If user is holding down the mouse button, reconfigure and end }
- else
- begin
- DialogPointer := GetNewDialog(runDlog, nil, POINTER(-1));
- SetPort(DialogPointer);
- DrawDialog(DialogPointer);
- TextFont(Geneva);
- TextSize(9);
- ForeColor(blueColor);
- getDItem(DialogPointer, 3, itemType, itemHandle, dispRect);
- EraseRect(dispRect);
- MoveTo(dispRect.left + 2, dispRect.bottom - 2);
- DrawString(concat('Version ', VERSION, ' of ', Compdate));
- ForeColor(redColor);
- getDItem(DialogPointer, 2, itemType, itemHandle, dispRect);
- MoveTo(dispRect.left + 2, dispRect.bottom - 2);
- DrawString('Reading Tabby info…');
- HelloTabby; { find out what's next on the launchpad }
- EraseRect(dispRect);
- MoveTo(dispRect.left + 2, dispRect.bottom - 2);
- DrawString('Reading Config file…');
-
- if ReadConfig then
- begin
- StuffItAvail := FindStuffIt;
- EraseRect(dispRect);
- ULRecSize := sizeOf(UserRecord);
- if Backup then
- begin
- MoveTo(dispRect.left + 2, dispRect.bottom - 2);
- DrawString('Backing up UserLog…');
- BackUserLog;
- EraseRect(dispRect)
- end;
- if SortUL then
- begin
- MoveTo(dispRect.left + 2, dispRect.bottom - 2);
- DrawString('Sorting UserLog…');
- SortUserLog;
- EraseRect(dispRect)
- end;
- if ZeroMin then
- begin
- MoveTo(dispRect.left + 2, dispRect.bottom - 2);
- DrawString('Clearing minutes used…');
- ZeroMinutes;
- EraseRect(dispRect)
- end;
- if ResetCL then
- begin
- MoveTo(dispRect.left + 2, dispRect.bottom - 2);
- DrawString('Resetting CallerLog…');
- ResetLog(CLPath);
- if MonthlyCLArc then
- DoMonthlyArc;
- EraseRect(dispRect)
- end;
- if ResetTL then
- begin
- MoveTo(dispRect.left + 2, dispRect.bottom - 2);
- DrawString('Resetting Tabby Log…');
- ResetLog(':Tabby:Tabby Log');
- EraseRect(dispRect)
- end;
- if TabbyLimit then
- begin
- MoveTo(dispRect.left + 2, dispRect.bottom - 2);
- DrawString('Trimming Tabby Log…');
- TrimLog(':Tabby:Tabby Log.Arch');
- EraseRect(dispRect)
- end;
- end; { if ReadConfig }
- if StuffItAvail then
- CloseStuffIt;
- DisposDialog(DialogPointer);
- if NextLaunch <> '' then
- LaunchNextAppl
- end
- end.